//
//  HEAudioRecordManage.m
//  HealthFamily
//
//  Created by 吴欧 on 2020/12/4.
//  Copyright © 2020 honglutec. All rights reserved.
//

#import "HEAudioRecordManage.h"
#import <AVFoundation/AVFoundation.h>


 
//录音保存为aac文件
#define kRecordAudioFile @"mRecord.aac"
//十分钟录音限制
#define ktime 600.0f

@interface HEAudioRecordManage ()<AVAudioRecorderDelegate>
 
@property (nonatomic, strong) NSTimer *levelTimer;
@property (nonatomic, strong) AVAudioRecorder *audioRecorder;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSString *recordFileName;
@property (nonatomic, assign) NSInteger curRecordTime;
@property (nonatomic, copy) updatePowerBlock updatePowerBlock;

@property (nonatomic, assign) HEAudioRecordState recordState;

@end

@implementation HEAudioRecordManage

+  (instancetype)sharedManager {
    
    static HEAudioRecordManage *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[HEAudioRecordManage alloc]init];
    });
    return manager;
    
}

- (instancetype)init {
    if(self == [super init]) {
        
        [self configAudioSession];
    }
    return self;
    
}

/**
 *  设置音频会话
 */
- (void)configAudioSession{
    AVAudioSession *audioSession=[AVAudioSession sharedInstance];
    //设置为播放和录音状态，以便可以在录制完之后播放录音
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [audioSession setActive:YES error:nil];
}
 
- (void)startRecord {
    
    _curRecordTime = 0;
    
    [self stopRecord];
    
    //创建录音文件保存路径
    NSURL *url = [self getSavePath];
    //创建录音格式设置
    NSDictionary *setting = [self getAudioSetting];
    //创建录音机
    NSError *error = nil;
    _audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
    _audioRecorder.delegate = self;
    _audioRecorder.meteringEnabled = YES;//如果要监控声波则必须设置为YES
    
    if (error) {
        NSLog(@"创建录音机对象时发生错误，错误信息：%@", error.localizedDescription);
        return ;
    }
     
    [self.audioRecorder record];
    _isRecording = [self.audioRecorder isRecording];
    [self startTimer];
}

- (void)endRecord {
    _recordState = HEAudioRecordStateFinish;
    [self stopRecord];
}
 
- (void)cancelRecord {
    _recordState = HEAudioRecordStateCancel;
    [self removeFileAtPath:self.recordFileName];
    [self stopRecord];
    [self stopTimer];
}

// 停止录音
- (void)stopRecord
{
    if (self.audioRecorder) {
        [self.audioRecorder stop];
    }
    self.isRecording = NO;
    self.audioRecorder = nil;
    [self stopTimer];
}
 
- (void)clearSource
{
    if (_isRecording) {
        [_audioRecorder stop];
    }
    _audioRecorder = nil;
    [self stopTimer];
}

#pragma  mark - 检测声波
- (void)startTimer {
    
    [self stopTimer];
    
    // 定时获取音量
    self.levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(powerTimerUpdate:) userInfo:nil repeats:true];
    [self.levelTimer fire];
    
    
    // 获取录音时间
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(recordTimeHander:) userInfo:nil repeats:true];
}

- (void)stopTimer {
    if (_levelTimer) {
        [_levelTimer invalidate];
        self.levelTimer = nil;
    }
    
    if (_timer) {
        [_timer invalidate];
        self.timer = nil;
    }
}

- (void)recordTimeHander:(NSTimer *)timer {
    [self timeline];
    _curRecordTime += 1;
}

- (void)powerTimerUpdate:(NSTimer *)timer{
    
    if (![[HEAudioRecordManage sharedManager] isRecording]) {
        return;
    }
    
    [self.audioRecorder updateMeters];//刷新音量数据
    //获取分贝  基本在0-1之间 可能超过1
    CGFloat lowPassResults = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0]));
    //分成10个等级
    int lastVolume = 0;
    if (lowPassResults <= 0.067) {
        lastVolume = 1;
    }else if (lowPassResults <= 0.134) {
        lastVolume = 2;
    }else if (lowPassResults <= 0.2) {
        lastVolume = 3;
    }else if (lowPassResults <= 0.267) {
        lastVolume = 4;
    }else if (lowPassResults <= 0.33) {
        lastVolume = 5;
    }else if (lowPassResults <= 0.4) {
        lastVolume = 6;
    }else if (lowPassResults <= 0.52) {
        lastVolume = 7;
    }else if (lowPassResults <= 0.64) {
        lastVolume = 8;
    }else if (lowPassResults <= 0.76) {
        lastVolume = 9;
    }else if (lowPassResults <= 0.88) {
        lastVolume = 10;
    }else{
        lastVolume = 11;
    }
    
    if (_updatePowerBlock) {
        _updatePowerBlock(lowPassResults);
    }
}

 
/**
 *  时间限制,到了ktime时间,停止录音
 */
-(void)timeline
{
    if (_curRecordTime > ktime)
    {
        [self stopRecord];
    }
}

/**
 *  获取当前时间
 *
 *  @return 当前时间返回值
 */
- (NSTimeInterval)accurateTime{
    NSDate *nowTime = [NSDate date];
    NSTimeInterval interval = [nowTime timeIntervalSince1970];
    return interval;
}


#pragma mark - 录音机代理方法
/**
 *  录音完成
 *
 *  @param recorder 录音机对象
 *  @param flag     是否成功
 */
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
    
    if (_recordState != HEAudioRecordStateFinish) {
        return;
    }
    if ([_delegate respondsToSelector:@selector(audioRecordFinishedWithFilePath:time:)]) {
        [_delegate audioRecordFinishedWithFilePath:_recordFileName time:_curRecordTime];
    }
    NSLog(@"录音完成!");
}


#pragma mark -
- (NSString *)cacheFileWidthPath:(NSString *)path Name:(NSString *)name {
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath= [cachePath stringByAppendingPathComponent:path];;
    
    // 先创建子目录
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:filePath]) {
        [fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
    }else{
        NSLog(@"已创建文件夹");
    }
    _recordFileName = [filePath stringByAppendingPathComponent:name];
    return _recordFileName;
}

- (void)removeFileAtPath:(NSString *)path {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        [fileManager removeItemAtPath:path error:nil];
    }
}


/**
 *  取得录音文件保存路径
 *
 *  @return 录音文件路径
 */
- (NSURL *)getSavePath{
    NSString *urlStr = [self cacheFileWidthPath:@"tempRecordPath" Name: [NSString stringWithFormat:@"%@.aac", [DYTools createUuid]]] ;
    NSLog(@"recordFile:%@",urlStr );
    NSURL *url=[NSURL fileURLWithPath:urlStr];
    return url;
}

/**
 *  取得录音文件设置
 *
 *  @return 录音设置
 */
- (NSDictionary *)getAudioSetting{
    NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
    //设置录音格式
    [dicM setObject:@(kAudioFormatMPEG4AAC) forKey:AVFormatIDKey];
    //设置录音采样率，8000是电话采样率，对于一般录音已经够了
    [dicM setObject:@(44100) forKey:AVSampleRateKey];
    //设置通道,这里采用单声道
    [dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
    //每个采样点位数,分为8、16、24、32
    [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
    //录音的质量
    [dicM setObject:@(AVAudioQualityHigh) forKey:AVEncoderAudioQualityKey];
    //是否使用浮点数采样
    [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
    return dicM;
}


- (void)updatePower:(updatePowerBlock)block {
    _updatePowerBlock = block;
}
 

/**
 *  dealloc释放资源
 */
-(void)dealloc
{
    [self clearSource];
}

@end
